package com.whfc.hj.util;

import com.whfc.common.util.ByteUtil;
import com.whfc.common.util.CrcUtil;
import com.whfc.common.util.JSONUtil;
import com.whfc.hj.entity.HjConst;
import com.whfc.hj.entity.HjMsg;
import com.whfc.hj.entity.HjMsg2011WC;
import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2020-12-08 14:26
 */
public class HjMsgUtil {

    private final static Pattern QN = Pattern.compile("QN=(\\d{17});");
    private final static Pattern ST = Pattern.compile("ST=(\\d+);");
    private final static Pattern CN = Pattern.compile("CN=(\\d+);");
    private final static Pattern PW = Pattern.compile("PW=(\\d+);");
    private final static Pattern MN = Pattern.compile("MN=(\\w+);");
    private final static Pattern FLAG = Pattern.compile("Flag=(\\w+);");
    private final static Pattern PNUM = Pattern.compile("PNUM=(\\w+);");
    private final static Pattern PNO = Pattern.compile("PNO=(\\w+);");
    private final static Pattern DATA_TIME = Pattern.compile("DataTime=(\\d{14});");
    private final static Pattern LA = Pattern.compile("LA-Rtd=(\\d+\\.?\\d+),LA-Flag=(\\w+);");
    private final static Pattern A01001 = Pattern.compile("a01001-Rtd=(\\d+\\.?\\d+),a01001-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern A01002 = Pattern.compile("a01002-Rtd=(\\d+\\.?\\d+),a01002-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern A01006 = Pattern.compile("a01006-Rtd=(\\d+\\.?\\d+),a01006-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern A01007 = Pattern.compile("a01007-Rtd=(\\d+\\.?\\d+),a01007-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern A01008 = Pattern.compile("a01008-Rtd=(\\d+\\.?\\d+),a01008-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern A34001 = Pattern.compile("a34001-Rtd=(\\d+\\.?\\d+),a34001-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern A34002 = Pattern.compile("a34002-Rtd=(\\d+\\.?\\d+),a34002-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern A34004 = Pattern.compile("a34004-Rtd=(\\d+\\.?\\d+),a34004-Flag=([N|F|M|S|D|C|T|B])");
    // ============================================
    private final static Pattern B03 = Pattern.compile("B03-Avg=(\\d+\\.?\\d+),B03-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern PM25 = Pattern.compile("PM25-Avg=(\\d+\\.?\\d+),PM25-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern PM10 = Pattern.compile("PM10-Avg=(\\d+\\.?\\d+),PM10-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern W02 = Pattern.compile("W02-Avg=(\\d+\\.?\\d+),W02-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern W01 = Pattern.compile("W01-Avg=(\\d+\\.?\\d+),W01-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern T01 = Pattern.compile("T01-Avg=(\\d+\\.?\\d+),T01-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern H01 = Pattern.compile("H01-Avg=(\\d+\\.?\\d+),H01-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern TSP = Pattern.compile("TSP-Avg=(\\d+\\.?\\d+),TSP-Flag=([N|F|M|S|D|C|T|B])");
    private final static Pattern ATMOS = Pattern.compile("ATMOS-Avg=(\\d+\\.?\\d+),ATMOS-Flag=([N|F|M|S|D|C|T|B])");

    /**
     * 编码
     *
     * @param msg
     * @return
     */
    public static String encode(HjMsg msg) {

        StringBuilder hjData = new StringBuilder();
        hjData.append(String.format("DataTime=%s;", msg.getDataTime()));

        if (!StringUtils.isEmpty(msg.getA34002Rtd())) {
            hjData.append(String.format("a34002-Rtd=%s,a34002-Flag=%s;", msg.getA34002Rtd(), msg.getA34002Flag()));
        }
        if (!StringUtils.isEmpty(msg.getA01001Rtd())) {
            hjData.append(String.format("a01001-Rtd=%s,a01001-Flag=%s;", msg.getA01001Rtd(), msg.getA01001Flag()));
        }
        if (!StringUtils.isEmpty(msg.getLaRtd())) {
            hjData.append(String.format("LA-Rtd=%s,LA-Flag=%s;", msg.getLaRtd(), msg.getLaFlag()));
        }
        if (!StringUtils.isEmpty(msg.getA01002Rtd())) {
            hjData.append(String.format("a01002-Rtd=%s,a01002-Flag=%s;", msg.getA01002Rtd(), msg.getA01002Flag()));
        }
        if (!StringUtils.isEmpty(msg.getA01008Rtd())) {
            hjData.append(String.format("a01008-Rtd=%s,a01008-Flag=%s;", msg.getA01008Rtd(), msg.getA01008Flag()));
        }
        if (!StringUtils.isEmpty(msg.getA01007Rtd())) {
            hjData.append(String.format("a01007-Rtd=%s,a01007-Flag=%s;", msg.getA01007Rtd(), msg.getA01007Flag()));
        }
        if (!StringUtils.isEmpty(msg.getA34004Rtd())) {
            hjData.append(String.format("a34004-Rtd=%s,a34004-Flag=%s;", msg.getA34004Rtd(), msg.getA34004Flag()));
        }
        if (!StringUtils.isEmpty(msg.getA34001Rtd())) {
            hjData.append(String.format("a34001-Rtd=%s,a34001-Flag=%s;", msg.getA34001Rtd(), msg.getA34001Flag()));
        }
        if (!StringUtils.isEmpty(msg.getA01006Rtd())) {
            hjData.append(String.format("a01006-Rtd=%s,a01006-Flag=%s;", msg.getA01006Rtd(), msg.getA01006Flag()));
        }

        StringBuilder data = new StringBuilder();
        data.append(String.format("QN=%s;", msg.getQn()));
        data.append(String.format("ST=%s;", msg.getSt()));
        data.append(String.format("CN=%s;", msg.getCn()));
        data.append(String.format("PW=%s;", HjConst.PW));
        data.append(String.format("MN=%s;", msg.getMn()));
        data.append(String.format("Flag=%s;", msg.getFlag()));
        data.append(HjConst.DATA_START);
        data.append(StringUtils.strip(hjData.toString(), ";"));
        data.append(HjConst.DATA_END);

        //crc
        int crc = crc16(data.toString());
        StringBuilder msgStr = new StringBuilder();
        msgStr.append(HjConst.HEAD);
        msgStr.append(String.format("%04d", data.length()));
        msgStr.append(data);
        msgStr.append(ByteUtil.toHexString(crc));
        msgStr.append(HjConst.TAIL);

        return msgStr.toString();
    }

    /**
     * 解码
     *
     * @param msgStr
     * @return
     */
    /**
     *          ##
     *          0361
     *          QN=20191021163058000;
     *          ST=22;
     *          CN=2011;
     *          PW=123456;
     *          MN=Y029000JH07609;
     *          Flag=5;
     *          CP=&&
     *          DataTime=20191021163000;
     *          LA-Rtd=56.8,LA-Flag=N;   		  //噪声
     *          a01001-Rtd=14.9,a01001-Flag=N;    //温度
     *          a01002-Rtd=81.1,a01002-Flag=N; 	  //湿度
     *          a01006-Rtd=97.16,a01006-Flag=N    //气压
     *          a01007-Rtd=0.8,a01007-Flag=N; 	  //风速
     *          a01008-Rtd=112,a01008-Flag=N; 	  //风向
     *          a34001-Rtd=96.8,a34001-Flag=N; 	  //tsp
     *          a34002-Rtd=81.0,a34002-Flag=N;    //PM10
     *          a34004-Rtd=46.4,a34004-Flag=N; 	  //pm25
     *          &&
     *          E101
     *          <CR><LF>
     */
    public static HjMsg decode(String msgStr) {
        String head = msgStr.substring(0, 2);
        int dataLength = Integer.parseInt(msgStr.substring(2, 6));
        String data = msgStr.substring(6, 6 + dataLength);
        int crc = Integer.parseInt(msgStr.substring(6 + dataLength, 6 + dataLength + 4), 16);
        String tail = msgStr.substring(6 + dataLength + 4, 6 + dataLength + 4 + 2);

        HjMsg msg = new HjMsg();
        msg.setHead(head);
        msg.setDataLength(dataLength);
        msg.setData(data);
        msg.setCrc(crc);
        msg.setTail(tail);

        Matcher matcher = null;
        matcher = QN.matcher(data);
        if (matcher.find()) {
            msg.setQn(matcher.group(1));
        }
        matcher = ST.matcher(data);
        if (matcher.find()) {
            msg.setSt(matcher.group(1));
        }
        matcher = CN.matcher(data);
        if (matcher.find()) {
            msg.setCn(matcher.group(1));
        }
        matcher = PW.matcher(data);
        if (matcher.find()) {
            msg.setPw(matcher.group(1));
        }
        matcher = MN.matcher(data);
        if (matcher.find()) {
            msg.setMn(matcher.group(1));
        }
        matcher = FLAG.matcher(data);
        if (matcher.find()) {
            msg.setFlag(Integer.parseInt(matcher.group(1)));
        }
        matcher = PNUM.matcher(data);
        if (matcher.find()) {
            msg.setPnum(Integer.parseInt(matcher.group(1)));
        }
        matcher = PNO.matcher(data);
        if (matcher.find()) {
            msg.setPno(Integer.parseInt(matcher.group(1)));
        }
        matcher = DATA_TIME.matcher(data);
        if (matcher.find()) {
            msg.setDataTime(matcher.group(1));
        }
        matcher = LA.matcher(data);
        if (matcher.find()) {
            msg.setLaRtd(matcher.group(1));
            msg.setLaFlag(matcher.group(2));
        }
        matcher = A01001.matcher(data);
        if (matcher.find()) {
            msg.setA01001Rtd(matcher.group(1));
            msg.setA01001Flag(matcher.group(2));
        }
        matcher = A01002.matcher(data);
        if (matcher.find()) {
            msg.setA01002Rtd(matcher.group(1));
            msg.setA01002Flag(matcher.group(2));
        }
        matcher = A01006.matcher(data);
        if (matcher.find()) {
            msg.setA01006Rtd(matcher.group(1));
            msg.setA01006Flag(matcher.group(2));
        }
        matcher = A01007.matcher(data);
        if (matcher.find()) {
            msg.setA01007Rtd(matcher.group(1));
            msg.setA01007Flag(matcher.group(2));
        }
        matcher = A01008.matcher(data);
        if (matcher.find()) {
            msg.setA01008Rtd(matcher.group(1));
            msg.setA01008Flag(matcher.group(2));
        }
        matcher = A34001.matcher(data);
        if (matcher.find()) {
            msg.setA34001Rtd(matcher.group(1));
            msg.setA34001Flag(matcher.group(2));
        }
        matcher = A34002.matcher(data);
        if (matcher.find()) {
            msg.setA34002Rtd(matcher.group(1));
            msg.setA34002Flag(matcher.group(2));
        }
        matcher = A34004.matcher(data);
        if (matcher.find()) {
            msg.setA34004Rtd(matcher.group(1));
            msg.setA34004Flag(matcher.group(2));
        }
        return msg;
    }

    /**
     * crc16
     *
     * @param data
     * @return
     */
    private static int crc16(String data) {
        return CrcUtil.crc16(data.getBytes());
    }

    public static void main(String[] args) {
        HjMsg msg = new HjMsg();
        msg.setQn("20191021163058000");
        msg.setSt("22");
        msg.setCn("2011");
        msg.setMn("Y029000JH07609");
        msg.setPw("123456");
        msg.setFlag(5);
        msg.setDataTime("20191021163000");
        msg.setLaRtd("56.8");
        msg.setLaFlag("N");
        msg.setA01001Rtd("14.9");
        msg.setA01001Flag("N");
        msg.setA01002Rtd("81.1");
        msg.setA01002Flag("N");
        msg.setA01006Rtd("97.16");
        msg.setA01006Flag("N");
        msg.setA01007Rtd("0.8");
        msg.setA01007Flag("N");
        msg.setA01008Rtd("112");
        msg.setA01008Flag("N");
        msg.setA34001Rtd("96.8");
        msg.setA34001Flag("N");
        msg.setA34002Rtd("81.0");
        msg.setA34002Flag("N");
        msg.setA34004Rtd("46.4");
        msg.setA34004Flag("N");

        String msgStr = HjMsgUtil.encode(msg);
        System.out.println(msgStr);
        System.out.println("length:" + msgStr.length());
        String s = "##0242ST=52;CN=2011;PW=123456;MN=Y3412000000002;CP=&&DataTime=20220512085300;B03-Avg=42.4,B03-Flag=N;PM25-Avg=6.1,PM25-Flag=N;PM10-Avg=16.3,PM10-Flag=N;W02-Avg=0.0,W02-Flag=N;W01-Avg=0.1,W01-Flag=N;T01-Avg=-40.0,T01-Flag=N;H01-Avg=0.0,H01-Flag=N;&&AB41";
        System.out.println(s.length());
        HjMsg2011WC msg1 = HjMsgUtil.decodeWC(s);
        System.out.println(JSONUtil.toPrettyString(msg1));
    }


    /**
     * 网畅扬尘设备2011指令解码
     * @param msgStr
     * @return
     */
    /**  网畅扬尘2011指令报文
     *      ##
     *      0242ST=52;
     *      CN=2011;
     *      PW=123456;
     *      MN=Y3412000000002;
     *      CP=&&
     *      DataTime=20220512085300;
     *      B03-Avg=42.4,B03-Flag=N;     // 噪声 ============常规八项
     *      PM25-Avg=6.1,PM25-Flag=N;    // pm2.5
     *      PM10-Avg=16.3,PM10-Flag=N;   // pm10
     *      W02-Avg=0.0,W02-Flag=N;      // 风速
     *      W01-Avg=0.1,W01-Flag=N;      // 风向
     *      T01-Avg=-40.0,T01-Flag=N;    // 温度
     *      H01-Avg=0.0,H01-Flag=N;      // 湿度
     *      TSP-Avg=220,TSP-Flag=N;      // tsp
     *      &&
     *      AB41
     *      <CR><LF>
     *      ===========================气体检测===============
     *      O3-Avg=23.4,O3-Flag=N;       // 臭氧
     *      CO-Avg=0.6,CO-Flag=N;        // 一氧化碳
     *      SO2-Avg=162.7,SO2-Flag=N;    // 二氧化硫
     *      NO2-Avg=23.8,NO2-Flag=N;     // 二氧化氮
     *      CO2-Avg=23.8,CO2-Flag=N;     // 二氧化氮
     */

    public static HjMsg2011WC decodeWC(String msgStr) {
        String head = msgStr.substring(0, 2);
        int dataLength = Integer.parseInt(msgStr.substring(2, 6));
        String data = msgStr.substring(6, 6 + dataLength);
        int crc = Integer.parseInt(msgStr.substring(6 + dataLength, 6 + dataLength + 4), 16);
//        String tail = msgStr.substring(6 + dataLength + 4, 6 + dataLength + 4 + 2);

        HjMsg2011WC msg = new HjMsg2011WC();
        msg.setHead(head);
        msg.setDataLength(dataLength);
        msg.setData(data);
        msg.setCrc(crc);
//        msg.setTail(tail);

        Matcher matcher = null;
        matcher = QN.matcher(data);
        if (matcher.find()) {
            msg.setQn(matcher.group(1));
        }
        matcher = ST.matcher(data);
        if (matcher.find()) {
            msg.setSt(matcher.group(1));
        }
        matcher = CN.matcher(data);
        if (matcher.find()) {
            msg.setCn(matcher.group(1));
        }
        matcher = PW.matcher(data);
        if (matcher.find()) {
            msg.setPw(matcher.group(1));
        }
        matcher = MN.matcher(data);
        if (matcher.find()) {
            msg.setMn(matcher.group(1));
        }
        matcher = PNUM.matcher(data);
        if (matcher.find()) {
            msg.setPnum(Integer.parseInt(matcher.group(1)));
        }
        matcher = PNO.matcher(data);
        if (matcher.find()) {
            msg.setPno(Integer.parseInt(matcher.group(1)));
        }
        matcher = DATA_TIME.matcher(data);
        if (matcher.find()) {
            msg.setDataTime(matcher.group(1));
        }
        matcher = B03.matcher(data);
        if (matcher.find()) {
            msg.setB03(matcher.group(1));
            msg.setB03Flag(matcher.group(2));
        }
        matcher = T01.matcher(data);
        if (matcher.find()) {
            msg.setT01(matcher.group(1));
            msg.setT01Flag(matcher.group(2));
        }
        matcher = H01.matcher(data);
        if (matcher.find()) {
            msg.setH01(matcher.group(1));
            msg.setH01Flag(matcher.group(2));
        }
        matcher = W02.matcher(data);
        if (matcher.find()) {
            msg.setW02(matcher.group(1));
            msg.setW02Flag(matcher.group(2));
        }
        matcher = W01.matcher(data);
        if (matcher.find()) {
            msg.setW01(matcher.group(1));
            msg.setW01Flag(matcher.group(2));
        }
        matcher = TSP.matcher(data);
        if (matcher.find()) {
            msg.setTsp(matcher.group(1));
            msg.setTspFlag(matcher.group(2));
        }
        matcher = ATMOS.matcher(data);
        if (matcher.find()) {
            msg.setAtmos(matcher.group(1));
            msg.setAtmosFlag(matcher.group(2));
        }
        matcher = PM10.matcher(data);
        if (matcher.find()) {
            msg.setPm10(matcher.group(1));
            msg.setPm10Flag(matcher.group(2));
        }
        matcher = PM25.matcher(data);
        if (matcher.find()) {
            msg.setPm25(matcher.group(1));
            msg.setPm25Flag(matcher.group(2));
        }
        return msg;
    }
}
